package com.funong.matrix.biz.system.domain;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.funong.matrix.biz.base.dao.SysFileBusinessDao;
import com.funong.matrix.biz.base.dao.SysFileInfoDao;
import com.funong.matrix.biz.base.entity.SysFileBusinessEntity;
import com.funong.matrix.biz.base.entity.SysFileInfoEntity;
import com.funong.matrix.biz.base.mapper.SysFileBusinessMapper;
import com.funong.matrix.biz.system.pojo.dto.FileBaseInfoDTO;
import com.funong.matrix.biz.system.pojo.dto.FileBusinessRelationDTO;
import com.funong.matrix.biz.system.pojo.dto.FileDTO;
import com.funong.matrix.core.dto.Result;
import com.funong.matrix.core.enums.FileCategoryType;
import com.funong.matrix.core.enums.ResultCodeEnum;
import com.funong.matrix.core.enums.StatusEnum;
import com.funong.matrix.core.utils.JwtUtils;
import com.funong.matrix.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author : NaNa
 * @since : 2023-05-26 18:19
 **/
@Slf4j
@Service
public class SysFileDomainDao {
    @Resource
    private SysFileBusinessDao fileBusinessDao;
    @Resource
    private SysFileInfoDao fileInfoDao;
    @Resource
    private SysFileBusinessMapper fileBusinessMapper;

    public SysFileInfoEntity saveFileInfo(FileBaseInfoDTO fileBaseInfoDTO) {
        String currentUserName = JwtUtils.getCurrentUserName();
        SysFileInfoEntity fileInfoEntity = new SysFileInfoEntity()
                .setNewFileName(fileBaseInfoDTO.getAttachName())
                .setOriginalFileName(fileBaseInfoDTO.getOriginalName())
                .setExtension(fileBaseInfoDTO.getAttachStuff())
                .setSize(fileBaseInfoDTO.getSizeInfo())
                //todo:当前操作人,fsType
                .setOperator(StringUtils.isNotBlank(currentUserName) ? currentUserName : "")
                .setPath(fileBaseInfoDTO.getAttachUrl())
                .setFsPath(fileBaseInfoDTO.getAttachUrl());
        fileInfoDao.save(fileInfoEntity);
        return fileInfoEntity;
    }

    public List<SysFileInfoEntity> getFileListByIds(List<Integer> fileIdList) {
        return fileInfoDao.getFileListByIds(fileIdList);
    }


    public Result recordFileRelation(FileBusinessRelationDTO relationDTO) {
//        this.deleteFileRelation(relationDTO.getBizId(), relationDTO.getCategoryType());
        if (CollectionUtils.isEmpty(relationDTO.getFileIdList())) {
            return Result.failure(ResultCodeEnum.FILE_EMPTY);
        }
        List<SysFileBusinessEntity> fileBusinessEntityList = relationDTO.getFileIdList().stream().map(fileId -> {
                    return new SysFileBusinessEntity()
                            .setBizModule(relationDTO.getModuleType())
                            .setBizCategory(relationDTO.getCategoryType())
                            .setBizId(relationDTO.getBizId())
                            .setStatus(StatusEnum.ENABLE.getValue())
                            .setFileId(fileId);
                }
        ).collect(Collectors.toList());
        fileBusinessEntityList.forEach(fileBusinessEntity -> fileBusinessDao.save(fileBusinessEntity));
        return Result.success("存储文件关系成功");
    }

    /**
     * 删除文件关系信息
     *
     * @param bizId        来源ID
     *                     {@link FileCategoryType}
     * @param categoryType 业务文件类型
     */
    public void deleteFileRelation(Integer bizId, String categoryType) {
        fileBusinessDao.deleteFileRelation(bizId, categoryType);
    }

    /**
     * 废弃文件关系信息，改状态为无效
     *
     * @param bizId        来源ID
     *                     {@link FileCategoryType}
     * @param categoryType 业务文件类型
     */
    public void dropFileRelation(Integer bizId, String categoryType, String memo) {
        fileBusinessDao.dropFileRelation(bizId, categoryType, memo);
    }


    /**
     * 废弃文件关系信息，改状态
     *
     * @param bizId                来源ID
     *                             {@link FileCategoryType}
     * @param fileCategoryTypeList 业务文件类型
     * @param statusEnum           状态（驳回只更新文件状态为无效，isdeleted=0，未删除）
     */
    public List<SysFileInfoEntity> getFileInfoByBizIdAndType(Integer bizId,
                                                             List<String> fileCategoryTypeList,
                                                             Integer statusEnum) {
        List<SysFileBusinessEntity> fileBusinessEntityList = fileBusinessDao.getFileInfoByBizIdAndType(bizId, fileCategoryTypeList, statusEnum);
        return this.covert2FileBaseInfo(fileBusinessEntityList);
    }

    /**
     * 根据来源ID、附件类型，查询附件信息
     *
     * @param bizId                来源ID
     * @param fileCategoryTypeList 附件类型集合
     * @return 附件信息
     */
    public Map<String, List<SysFileInfoEntity>> getFileMapByBizIdAndType(Integer bizId, List<String> fileCategoryTypeList, Integer status) {
        List<SysFileInfoEntity> fileBaseInfoList = this.getFileInfoByBizIdAndType(bizId, fileCategoryTypeList, status);
        Map<String, List<SysFileInfoEntity>> fileBaseInfoMap = fileBaseInfoList.stream().collect(Collectors.groupingBy(SysFileInfoEntity::getFileCategoryType));
        fileCategoryTypeList.forEach(it -> {
            if (CollectionUtils.isEmpty(fileBaseInfoMap.get(it))) {
                fileBaseInfoMap.put(it, Collections.emptyList());
            }
        });
        return fileBaseInfoMap;
    }

    /**
     * 拼接文件基本信息-展示
     *
     * @param fileBusinessEntityList 文件关系
     * @return
     */
    private List<SysFileInfoEntity> covert2FileBaseInfo(List<SysFileBusinessEntity> fileBusinessEntityList) {
        List<Integer> attachFileIds = fileBusinessEntityList.stream()
                .map(SysFileBusinessEntity::getFileId)
                .collect(Collectors.toList());
        List<SysFileInfoEntity> fileInfoEntityList = !CollectionUtils.isEmpty(attachFileIds) ? fileInfoDao.getFileListByIds(attachFileIds) : Collections.emptyList();
        //Map: 文件id，文件类型
        Map<Integer, List<SysFileBusinessEntity>> fileIdTypeMap = fileBusinessEntityList.stream().collect(Collectors.groupingBy(SysFileBusinessEntity::getFileId));
        return fileInfoEntityList.stream()
                .map(fileInfoEntity -> {
                    SysFileBusinessEntity fileBusinessEntity = fileIdTypeMap.get(fileInfoEntity.getId()).get(0);
                    fileInfoEntity.setFileCategoryType(fileBusinessEntity.getBizCategory())
                            .setFileUrl(fileInfoEntity.getPath())
                            .setFilePathUrl(fileInfoEntity.getPath())
//                            .setFileCategoryTypeInfo(FileCategoryType.valueOf(fileBusinessEntity.getBizCategory()).getMsg())
                            .setBizFileStatus(fileBusinessEntity.getStatus())
                            .setFileBusinessId(fileBusinessEntity.getId());
                    fileInfoEntity.setMemo(StringUtils.isBlank(fileBusinessEntity.getMemo()) ? fileBusinessEntity.getMemo() : "");
                    return fileInfoEntity;
                })
                .collect(Collectors.toList());
    }

    public SysFileBusinessEntity saveFileBusiness(SysFileBusinessEntity sysFileBusinessEntity) {
        fileBusinessDao.save(sysFileBusinessEntity);
        return sysFileBusinessEntity;
    }

    public Integer queryFileCount(SysFileBusinessEntity sysFileBusinessEntity) {
        return fileBusinessDao.queryFileCount(sysFileBusinessEntity);
    }

    public void updateFileBusiness(SysFileBusinessEntity sysFileBusinessEntity) {
        fileBusinessDao.updateById(sysFileBusinessEntity);
    }

    public List<SysFileBusinessEntity> queryFileBusinessList(SysFileBusinessEntity sysFileBusinessEntity) {
        return fileBusinessDao.queryFileBusinessList(sysFileBusinessEntity);
    }

    public IPage<SysFileBusinessEntity> queryContractFile(Page page, SysFileBusinessEntity sysFileBusinessEntity) {
        return fileBusinessDao.queryContractFile(page, sysFileBusinessEntity);
    }

    /**
     * 保存文件关系
     *
     * @param bizModule
     * @param bizId
     * @param bizCategory
     * @param fileList
     */
    public void saveFileBusiness(String bizModule, Integer bizId, String bizCategory, List<FileDTO> fileList) {
        // 删除旧的
        fileBusinessDao.deleteFileBusiness(bizModule, bizId, bizCategory);
        // 插入新的
        if (CollUtil.isNotEmpty(fileList)) {
            List<SysFileBusinessEntity> list = new ArrayList<>();
            fileList.forEach(fileDTO -> {
                list.add(new SysFileBusinessEntity()
                        .setBizModule(bizModule.toLowerCase())
                        .setBizId(bizId)
                        .setBizCategory(bizCategory.toLowerCase())
                        .setStatus(StatusEnum.ENABLE.getValue())
                        .setFileId(fileDTO.getId()));
            });
            fileBusinessDao.saveBatch(list);
        }
    }

    /**
     * 查询文件列表
     *
     * @param bizModule
     * @param bizId
     * @param bizCategory
     * @return
     */
    public List<SysFileInfoEntity> queryFileInfo(String bizModule, Integer bizId, String bizCategory) {
        List<SysFileBusinessEntity> sysFileBusinessEntityList = fileBusinessDao.queryFileBusiness(bizModule, bizId, bizCategory);
        List<Integer> idList = new ArrayList<>();
        sysFileBusinessEntityList.forEach(item -> {
            idList.add(item.getFileId());
        });
        if (CollUtil.isEmpty(idList)) {
            return new ArrayList<>();
        }
        return this.getFileListByIds(idList);
    }
}
